#include "sceneObjectManager.h"


SceneObjectManager::SceneObjectManager(ID3D10Device *device, ShaderManager *shaderManager)
{
	m_d3dDevice=device;
	m_ShaderManager=shaderManager;
	;

}

SceneObjectManager::~SceneObjectManager()
{
	if(m_d3dDevice)
	{
		m_d3dDevice->Release();
		m_d3dDevice=NULL;
	}

	if(m_ShaderManager)
		delete(m_ShaderManager);

	std::map<std::string,std::vector<SceneObject*>>::iterator it;

	for(it=m_ObjectMap.begin(); it!=m_ObjectMap.end(); it++)
	{
		std::vector<SceneObject*>::iterator jt;
		
		std::vector<SceneObject*> tmp=it->second;

		for(jt=tmp.begin(); jt!=tmp.end(); jt++)
			tmp.erase(jt);
	}
	
	
}

void SceneObjectManager::AddObject(DrawableObject * object, std::string technique, D3DXVECTOR3 position, D3DXQUATERNION rotation )
{
	if(m_ShaderManager->getTechniqueByName(technique)==NULL)
		return;

	SceneObject * sceneObject=new SceneObject();
	sceneObject->m_Object=object;
	D3DXMATRIX translationMatrix;
	D3DXMatrixTranslation(&translationMatrix,position.x,position.y,position.z);
	sceneObject->m_TranslationMatrix=translationMatrix;
	sceneObject->m_Rotation=rotation;

	if(m_ObjectMap.find(technique)==m_ObjectMap.end())
	{
		std::vector<SceneObject*> newVector;
		newVector.push_back(sceneObject);
		m_ObjectMap[technique]=newVector;
	}
	else
	{
		std::vector<SceneObject*> oldVector=m_ObjectMap[technique];
		oldVector.push_back(sceneObject);
		m_ObjectMap[technique]=oldVector;
	}
}



void SceneObjectManager::Draw()
{
	


	D3D10_TECHNIQUE_DESC techDesc;
	D3DXMATRIX worldMatrix;




	std::map<std::string,std::vector<SceneObject*>>::iterator it;

	for(it=m_ObjectMap.begin(); it!=m_ObjectMap.end(); it++)
	{
		//get technique		
		ID3D10EffectTechnique * technique=m_ShaderManager->getTechniqueByName(it->first);
		technique->GetDesc(&techDesc);

		//get list of objects associated with current technique
		std::vector<SceneObject*> objectVector=it->second;
		

			
			//draw all the objects
		std::vector<SceneObject*>::iterator jt;
		for(jt=objectVector.begin(); jt!=objectVector.end(); jt++)
		{
			
			
			
			D3DXMATRIX worldMatrix;
			D3DXMATRIX rotationMatrix;

			D3DXMatrixRotationQuaternion(&rotationMatrix,&(*jt)->m_Rotation);
			D3DXMatrixMultiply(&worldMatrix, &rotationMatrix,&(*jt)->m_TranslationMatrix);

			m_ShaderManager->setMatrixVariable("World", static_cast<float*>(worldMatrix) );

			for( UINT p = 0; p < techDesc.Passes; ++p )
			{

				technique->GetPassByIndex(p)->Apply( 0 );
				(*jt)->m_Object->Draw();
			}

		}

	}


}

void SceneObjectManager::SetEyeParameters( ICamera * camera )
{
	m_EyeDirection=camera->getEyeDirection();
	m_EyePosition=camera->getEyePosition();
}